import CONSTANT from '../json/constant.json';

export const UPLOAD_TYPES = {
  TYPE_1: 1, // 虚线圆
  TYPE_2: 2, // 空心圆
  TYPE_3: 3, // 浅色圆
  TYPE_4: 4, // 实心圆
  TYPE_5: 5, // 虚线方块
  TYPE_6: 6, // 空心方块
  TYPE_7: 7, // 浅色方块
  TYPE_8: 8, // 实心方块
  TYPE_9: 9, // 双色圆
  TYPE_10: 10, // 双色鼓形
  TYPE_11: 11, // 实心鼓形
  TYPE_12: 12, // 消失
};

export function drawMark(ele: HTMLElement) {
  ele.style.top = `${-12}px`;
  ele.style.left = `${CONSTANT.RECT_WIDTH / 2}px`;
  ele.style.backgroundColor = CONSTANT.MARK_BACKGROUND_COLOR;
  ele.style.color = CONSTANT.MARK_TEXT_COLOR;
  ele.style.fontSize = '12px';
  ele.style.position = 'absolute';
  ele.style.padding = '2px 6px';
  ele.style.borderRadius = '10px';
  ele.style.border = '2px solid #FFFFFF';
  ele.style.transition = 'opacity 0.2s ease-out';
  ele.style.opacity = '0';
}

export function getMarkText(historyList: any[]) {
  const combination12 = [
    UPLOAD_TYPES.TYPE_1,
    UPLOAD_TYPES.TYPE_3,
    UPLOAD_TYPES.TYPE_5,
    UPLOAD_TYPES.TYPE_7,
    UPLOAD_TYPES.TYPE_12,
  ];
  const result = historyList.filter(
    (item) => !combination12.includes(item.type)
  );
  return result.length;
}

function afterAnimation(ele: HTMLElement, height: number, width: number) {
  setTimeout(() => {
    ele.style.width = `${width}px`;
    ele.style.height = `${height}px`;
    const mark: any = ele.children[0];
    if (mark) {
      mark.style.opacity = '1';
    }
  });
}

function drawDottedCircle(ele: HTMLElement, color: string) {
  ele.style.backgroundColor = 'white';
  ele.style.border = `2px dotted ${color}`;
  ele.style.borderRadius = '50%';
  afterAnimation(ele, CONSTANT.CIRCLE_DIAMETER, CONSTANT.CIRCLE_DIAMETER);
}

function drawHollowCircle(ele: HTMLElement, color: string) {
  ele.style.backgroundColor = 'white';
  ele.style.border = `2px solid ${color}`;
  ele.style.borderRadius = '50%';
  afterAnimation(ele, CONSTANT.CIRCLE_DIAMETER, CONSTANT.CIRCLE_DIAMETER);
}

function drawLightColorCircle(
  ele: HTMLElement,
  color: string,
  lightColor: string
) {
  ele.style.backgroundColor = lightColor;
  ele.style.border = `2px solid ${color}`;
  ele.style.borderRadius = '50%';
  afterAnimation(ele, CONSTANT.CIRCLE_DIAMETER, CONSTANT.CIRCLE_DIAMETER);
}

function drawSolidCircle(ele: HTMLElement, color: string) {
  ele.style.backgroundColor = color;
  ele.style.borderRadius = '50%';
  afterAnimation(ele, CONSTANT.CIRCLE_DIAMETER, CONSTANT.CIRCLE_DIAMETER);
}

function drawDoubleColorCircle(ele: HTMLElement, color: string) {
  ele.style.background = `linear-gradient(to right, ${color} 0%,${color} 50%,white 50%,white 100%)`;
  ele.style.border = `2px solid ${color}`;
  ele.style.borderRadius = '50%';
  afterAnimation(ele, CONSTANT.CIRCLE_DIAMETER, CONSTANT.CIRCLE_DIAMETER);
}

function drawDottedRect(ele: HTMLElement, color: string) {
  ele.style.backgroundColor = 'white';
  ele.style.border = `2px dotted ${color}`;
  ele.style.borderRadius = '4px';
  afterAnimation(ele, CONSTANT.RECT_WIDTH, CONSTANT.RECT_WIDTH);
}

function drawHollowRect(ele: HTMLElement, color: string) {
  ele.style.backgroundColor = 'white';
  ele.style.border = `2px solid ${color}`;
  ele.style.borderRadius = '4px';
  afterAnimation(ele, CONSTANT.RECT_WIDTH, CONSTANT.RECT_WIDTH);
}

function drawLightColorRect(
  ele: HTMLElement,
  color: string,
  lightColor: string
) {
  ele.style.backgroundColor = lightColor;
  ele.style.border = `2px solid ${color}`;
  ele.style.borderRadius = '4px';
  afterAnimation(ele, CONSTANT.RECT_WIDTH, CONSTANT.RECT_WIDTH);
}

function drawSolidRect(ele: HTMLElement, color: string) {
  ele.style.backgroundColor = color;
  ele.style.borderRadius = '4px';
  afterAnimation(ele, CONSTANT.RECT_WIDTH, CONSTANT.RECT_WIDTH);
}

function drawDoubleColorDrum(ele: HTMLElement, color: string) {
  ele.style.background = `linear-gradient(to right, ${color} 0%,${color} 50%,white 50%,white 100%)`;
  ele.style.border = `2px solid ${color}`;
  ele.style.borderRadius = '40%';
  afterAnimation(ele, CONSTANT.DRUM_HEIGHT, CONSTANT.DRUM_WIDTH);
}

function drawSolidDrum(ele: HTMLElement, color: string) {
  ele.style.backgroundColor = color;
  ele.style.borderRadius = '40%';
  afterAnimation(ele, CONSTANT.DRUM_HEIGHT, CONSTANT.DRUM_WIDTH);
}

function disappear(ele: HTMLElement) {
  ele.style.display = 'none';
}

export function drawEvent(
  ele: HTMLElement,
  left: number,
  index: number,
  type: number
) {
  const eventTop =
    (index * 2 + 1.5) * CONSTANT.LINE_HEIGHT -
    CONSTANT.RECT_WIDTH / 2 +
    CONSTANT.LINE_WEIGHT / 2;
  const eventColor =
    index === 0
      ? CONSTANT.SELF_TEAM_COLOR
      : CONSTANT.TEAM_COLOR_LIST[(index - 1) % CONSTANT.TEAM_COLOR_LIST.length];
  const lightColor =
    index === 0
      ? CONSTANT.SELF_LIGHT_COLOR
      : CONSTANT.LIGHT_COLOR_LIST[
          (index - 1) % CONSTANT.TEAM_COLOR_LIST.length
        ];
  ele.style.left = `${left}px`;
  ele.style.top = `${eventTop}px`;
  ele.style.position = 'absolute';
  ele.style.transition = 'height 0.2s ease-out, width 0.2s ease-out';
  ele.style.cursor = 'pointer';
  ele.style.width = '0';
  ele.style.height = '0';
  switch (type) {
    case UPLOAD_TYPES.TYPE_1:
      drawDottedCircle(ele, eventColor);
      break;
    case UPLOAD_TYPES.TYPE_2:
      drawHollowCircle(ele, eventColor);
      break;
    case UPLOAD_TYPES.TYPE_3:
      drawLightColorCircle(ele, eventColor, lightColor);
      break;
    case UPLOAD_TYPES.TYPE_4:
      drawSolidCircle(ele, eventColor);
      break;
    case UPLOAD_TYPES.TYPE_5:
      drawDottedRect(ele, eventColor);
      break;
    case UPLOAD_TYPES.TYPE_6:
      drawHollowRect(ele, eventColor);
      break;
    case UPLOAD_TYPES.TYPE_7:
      drawLightColorRect(ele, eventColor, lightColor);
      break;
    case UPLOAD_TYPES.TYPE_8:
      drawSolidRect(ele, eventColor);
      break;
    case UPLOAD_TYPES.TYPE_9:
      drawDoubleColorCircle(ele, eventColor);
      break;
    case UPLOAD_TYPES.TYPE_10:
      drawDoubleColorDrum(ele, eventColor);
      break;
    case UPLOAD_TYPES.TYPE_11:
      drawSolidDrum(ele, eventColor);
      break;
    case UPLOAD_TYPES.TYPE_12:
      disappear(ele);
      break;
    default:
      disappear(ele);
  }
}

// 自己团队upload类型计算
function getSelfTeamUploadType(typeA: number, typeB: number) {
  let result = UPLOAD_TYPES.TYPE_12;
  const combination12 = [
    UPLOAD_TYPES.TYPE_1,
    UPLOAD_TYPES.TYPE_3,
    UPLOAD_TYPES.TYPE_5,
    UPLOAD_TYPES.TYPE_7,
    UPLOAD_TYPES.TYPE_12,
  ];
  const combination11 = [
    UPLOAD_TYPES.TYPE_4,
    UPLOAD_TYPES.TYPE_8,
    UPLOAD_TYPES.TYPE_11,
  ];
  if (combination12.includes(typeA) && combination12.includes(typeB)) {
    result = UPLOAD_TYPES.TYPE_12;
  } else if (typeA === typeB) {
    result = typeA;
  } else if (combination11.includes(typeA) && combination11.includes(typeB)) {
    result = UPLOAD_TYPES.TYPE_11;
  } else if (combination12.includes(typeA)) {
    result = typeB;
  } else if (combination12.includes(typeB)) {
    result = typeA;
  }
  return result;
}

// 其他团队upload类型计算
function getOtherTeamUploadType(typeA: number, typeB: number) {
  let result = UPLOAD_TYPES.TYPE_12;
  const combination9 = [
    UPLOAD_TYPES.TYPE_2,
    UPLOAD_TYPES.TYPE_4,
    UPLOAD_TYPES.TYPE_9,
  ];
  const combination11 = [
    UPLOAD_TYPES.TYPE_4,
    UPLOAD_TYPES.TYPE_8,
    UPLOAD_TYPES.TYPE_11,
  ];
  if (typeA === typeB) {
    result = typeA;
  } else if (combination9.includes(typeA) && combination9.includes(typeB)) {
    result = UPLOAD_TYPES.TYPE_9;
  } else if (combination11.includes(typeA) && combination11.includes(typeB)) {
    result = UPLOAD_TYPES.TYPE_11;
  } else {
    result = UPLOAD_TYPES.TYPE_10;
  }
  return result;
}

// 获取要展示的upload的map
export function getUploadMap(
  uploadHistory: any[],
  times: number,
  totalTime: number,
  canvasWidth: number,
  index: number
) {
  const result = new Map();
  const timeList = [];
  const getTypeFunction =
    index === 0 ? getSelfTeamUploadType : getOtherTeamUploadType;
  for (let i = 0; i < uploadHistory.length; i++) {
    if (i === 0) {
      result.set(uploadHistory[i].uploadTime, uploadHistory[i]);
      timeList.push(uploadHistory[i].uploadTime);
    } else {
      const uploadTimeA: Date = timeList[timeList.length - 1];
      const uploadTimeB: Date = uploadHistory[i].uploadTime;
      const timeDiff =
        (((uploadTimeB.getTime() - uploadTimeA.getTime()) / totalTime) *
          canvasWidth) /
        times;
      if (
        timeDiff <= CONSTANT.RECT_WIDTH &&
        !('children' in result.get(uploadTimeA))
      ) {
        // 还没有children属性
        const type = getTypeFunction(
          result.get(uploadTimeA).type,
          uploadHistory[i].type
        );
        const newHistory = {
          uploadTime: uploadTimeA,
          type,
          children: [result.get(uploadTimeA), uploadHistory[i]],
        };
        result.set(uploadTimeA, newHistory);
      } else if (
        timeDiff <= CONSTANT.RECT_WIDTH &&
        'children' in result.get(uploadTimeA)
      ) {
        // 已经有children属性
        const type = getTypeFunction(
          result.get(uploadTimeA).type,
          uploadHistory[i].type
        );
        result.get(uploadTimeA).children.push(uploadHistory[i]);
        result.get(uploadTimeA).type = type;
      } else {
        result.set(uploadHistory[i].uploadTime, uploadHistory[i]);
        timeList.push(uploadHistory[i].uploadTime);
      }
    }
  }
  return result;
}
